<template>
    <div>
        <Row style="margin:5px 0px 5px 5px">
            <i-col span="2" >
                <Button  size="default"  type="primary" @click="btn_refresh" >刷新</Button>
            </i-col>
            <i-col  span="3">
                <Button  size="default"  type="primary" @click="btn_add_task" >添加任务</Button>
            </i-col>
        </Row>

        <i-table size="default"   border stripe :columns="format" :data="show_list" :height="sharedState.tableHeight" >
            <template slot-scope="{  index }" slot="action" >
                <Button  size="default"  type="primary"    shape="circle" style="margin:3px 2px"   @click="btn_edit_task(index)">改</Button>
                <Button  size="default"  type="primary"    shape="circle"  style="margin:3px 2px"     @click="btn_run_once_task(index)">检</Button> 
                <Button  size="default"  type="primary"    shape="circle"  style="margin:3px 2px"     @click="btn_start_task(index)">启</Button>
                <Button  size="default"  type="primary"     shape="circle" style="margin:3px 2px"    @click="btn_stop_task(index)">停</Button>
                <Button  size="default"  type="error"    shape="circle"  style="margin:3px 2px"   @click="btn_delete_task(index)">删</Button>
                <Button  size="default"  type="primary"    shape="circle"  style="margin:3px 2px"    @click="btn_get_log(index)">log</Button>
                <Button  size="default"  type="error"  shape="circle"  style="margin:3px 2px"   @click="btn_delete_task_log(index)">清</Button>
            </template>
        </i-table >
        <div style="text-align: center;margin-top: 10px;">
            <Page ref="page" :total="total" :page-size="pageSize"  @on-change="changePage" @on-page-size-change="changePageSize"  show-total show-sizer/>
        </div>
        <!-- 新增 -->
        <Modal v-model="show_add_task_modal" width="800" draggable>
            <p slot="header" style="color:#f60;text-align:center">
                <span>添加任务 </span>
            </p>
            <div >
                <Form ref="task" :model="task" :rules="add_rules" label-position="left"  :label-width="100" inline>
                    <Form-Item label="任务名称:"  prop="name" style="width:350px" >
                        <Input type="text"  v-model="task.name" />
                    </Form-Item> 
                </Form> 
            </div>
            <div slot="footer">
                <Button  size="default"  type="primary"   @click="submit_add_task('task')">提交</Button>
            </div>
        </Modal>
        <!-- 编辑 -->
        <Modal v-model="show_edit_task_modal" width="800" :mask="true"  class-name="vertical-center-modal">
            <!-- <p slot="header" style="color:#f60;text-align:center">
                <span>编辑任务 </span>
            </p> -->
            <div style="color:#f60;margin-bottom:5px"><h3>编辑任务</h3></div>
            <div >
                <Form ref="task_edit" :model="task_edit" :rules="edit_rules" label-position="left"  :label-width="100" inline>
                    <Form-Item label="任务名称:"  prop="name" style="width:350px" >
                        <Input size="default" type="text"  v-model="task_edit.name" />
                    </Form-Item> 
                    <Form-Item label="运行周期:"  prop="spec" style="width:350px">
                        <Input  size="default" type="text"   v-model="task_edit.spec" placeholder="秒 分 时 天 月 星期" />
                    </Form-Item> 
                    <Form-Item label="节点:"  prop="node" style="width:750px">
                        <Transfer :data="nodeData" 
                            :target-keys="nodeKeys" 
                            :list-style="listStyle" 
                            :render-format="renderX"
                            :titles="['未选节点','已选节点']"
                            @on-change="handleChangeNode"
                        ></Transfer>
                    </Form-Item>
                    <div>
                    <Form-Item label="类型:"  prop="type" style="width:200px">
                        <Select  size="default" v-model="task_edit.type">
                            <Option :key="1" :value="1">command</Option>
                            <Option :key="2" :value="2">package</Option>
                        </Select>
                    </Form-Item> 
                    <Form-Item label="命令:"  prop="command" v-if="task_edit.type==1"  style="width:310px"> 
                        <Input  size="default" type="text"  v-model="task_edit.command" />
                    </Form-Item> 
                    

                    <Form-Item label="上传任务包:"  prop="package" v-if="task_edit.type==2" style="width:310px">
                        <Upload class="avatar-uploader" type="drag" :on-success="uploadSuccess" :action="uploadUrl"  :max-size="10240"  accept=".zip" :show-upload-list="false">
                            <div >
                                    <Icon type="ios-cloud-upload" size="30" style="color: #3399ff"></Icon>
                                    <span>  (提示:只支持zip类型)</span>
                            </div>
                        </Upload>  
                    </Form-Item> 
                    <Form-Item>
                        <template v-if="task_edit.type==2" > 
                            <a :href="task_edit.package">任务包链接</a> 
                        </template>
                    </Form-Item>
                    </div>
                    <Form-Item label="语言:"  prop="language" v-if="task_edit.type==2" style="width:200px">
                        <Select  size="default" v-model="task_edit.language" >
                            <Option v-for="lang in language_list" :key="lang"  :value="lang">{{ lang }}</Option>
                        </Select>
                    </Form-Item> 
                    <Form-Item label="运行文件:"  prop="run_file" v-if="task_edit.type==2"  style="width:310px">
                        <Input  size="default" type="text"  v-model="task_edit.run_file" placeholder="manage.py/main.go" />
                    </Form-Item> 

                    <Form-Item label="超时(>30):"  prop="timeout"  style="width:100px">
                        <InputNumber  size="default" v-model="task_edit.timeout" />
                    </Form-Item> 
                    <Form-Item label="参数:"  prop="params"  v-if="task_edit.type==2"  style="width:350px">
                        <Input  size="default" type="text"  v-model="task_edit.params" placeholder="直接写参数值，空格分隔" />
                    </Form-Item> 

                    <Form-Item label="接收邮件:"  prop="receivers" style="width:350px">
                        <Input  size="default" type="text"  v-model="task_edit.receivers" />
                    </Form-Item> 
                    <Form-Item label="备注:"  prop="description" style="width:710px" >
                        <Input  size="default" type="textarea" :autosize="{minRows: 2,maxRows: 5}"  v-model="task_edit.description" placeholder="一般写参数说明" /> 
                    </Form-Item> 
                </Form> 
            </div>


            <Button  size="small"  type="primary"   @click="submit_edit_task('task_edit')">提交</Button>
            <div slot="footer">
                
            </div>
        </Modal>
        <!-- 日志 -->
        <TaskLogModal :isShow="show_task_log_modal" boxwidth="80vw" :taskId="taskId" @closeModal="closeTaskLogModal" ></TaskLogModal>
    </div>
</template>
<script>

import { 
    get_task_list,
    task_node_simple_list,
    upload_file,
    task_add,
    task_update,
    task_detail,
    task_start,
    task_stop,
    task_run_once,
    task_delete,
    task_log_delete,

} from  '@/api'
import { post } from '@/api/http'
import { colors } from '@/common/util' 
import store from '@/store'
import TaskLogModal from './lib/log'
import { formatUtcTime } from '@/common/util' 


const STATE_STOPPED = 0
const STATE_RUNNING = 1
const STATE_PAUSED = 2

export default {
    components: {
        TaskLogModal,
    },
    data() {
        return {
            sharedState: store.state,
            uploadUrl: upload_file,
            format: [
                {
                    title: '序号',key: 'id',width:80,
                    render: (h,params) => {
                        return h('a',{
                            style: {
                                color: 'blue'
                            },
                            on: {
                                click: ()=>{                       
                                    this.handleLink(params);
                                }
                            }
                        },params.row.id) 
                    }
                },
                {
                    title: '任务名称',key: 'name',width:150,
                },
                {
                    title: '节点',key: 'nodes'
                },
                {
                    title: 'Cron表达式',key: 'spec',width:200,
                },
                {
                    title: '状态',key: 'status',
                    render: (h,params) => {
                        let value = params.row.status
                        if(value == STATE_RUNNING ){
                            return h('span',{
                                style: {
                                    color: colors['green'],
                                }
                            },'运行')
                        } else if (value == STATE_STOPPED ){
                            return h('span',{
                                style: {
                                    color: colors['red'],
                                }
                            },'停止')
                        }else if (value == STATE_PAUSED ){
                            return h('span',{
                                style: {
                                    color: colors['yellow'],
                                }
                            },'暂停')
                        }else{
                            return h('span',{
                                style: {
                                    color: colors['gray'],
                                }
                            },'未知')
                        }
                    }
                },
                {
                    title: '下次运行时间',key: 'next_run_time',width:220,
                    render:(h,params) => {
                        let value = params.row.next_run_time
                        let toLocal = formatUtcTime(value)
                        return h('span',toLocal)
                    }
                },
                {
                    title: '操作',slot: 'action',width: 250,align: 'center'
                }
            ],
            // 新增
            show_add_task_modal:false,
            task: {
                name: 'task1',
            },

            fileName: '',
            language_list: ['shell','python','go'],
            nodeData: [],
            nodeKeys:[],
            listStyle: {
                width: '273px',
                height: '120px'
            },
            node_list: [],
            add_rules: {
                name:[
                    {required: true,message:"请输入任务名称",trigger: 'blur'},
                ],
            },

            // 编辑
            task_edit: {
                name: 'task1',
                type: 2,
                spec: "*/1 * * * *",

                command: 'python main.py',
                
                package: '',
                params: '',
                language: 'python',
                run_file: '',

                timeout: 5,
                receivers: '',
                nodes: [],
                description:'',
            },
            edit_rules: {
                name:[
                    {required: true,message:"请输入任务名称",trigger: 'blur'},
                ],
                spec:[
                    {required: true,message:"请输入运行周期",trigger: 'blur'},
                ],
            },
            show_edit_task_modal:false,
            // 日志
            show_task_log_modal: false,
            taskId: -1,
            // 分页
            // total_list: [],
            show_list: [],
            total: 0,
            pageSize: 10,

        }

    },
    methods: {
        btn_refresh(){
            this.refresh()
        },
        // 链接点击事件，进入详情页
        handleLink(params){
            let id = params.row.id
            const { href } = this.$router.resolve({
                name: 'taskDetail'
            });
            window.open(href+"?id="+id, '_blank');
        },
        uploadSuccess(res){
            // let info = JSON.stringify(res)
            this.fileName = res.name
            this.task_edit.package = res.url;
            this.$Message.success('上传成功')
        },
        btn_delete_task_log(index){
            let id = this.show_list[index].id
            let data = {"id":id}
            let result = confirm("确定要删除id为"+id+"的任务日志吗?")
            if(result == false) return false
            post(task_log_delete,data).then( (response) => {
                if(response.status==200) {
                    this.$Message.success('删除task日志成功')
                    this.refresh()
                }else {
                    alert("删除task日志失败")
                }
            })      
        },
        btn_delete_task(index){
            let id = this.show_list[index].id
            let data = {"id":id}
            let result = confirm("确定要删除id为"+id+"的任务吗?")
            if(result == false) return false
            post(task_delete,data).then( (response) => {
                if(response.status==200) {
                    this.$Message.success('删除task成功')
                    this.refresh()
                }else {
                    alert("删除task失败")
                }
            })      
        },
        btn_get_log(index){
            this.taskId = this.show_list[index].id
            this.show_task_log_modal=true
        },
        closeTaskLogModal(){
            this.show_task_log_modal = false
        },

        str_to_num_array(str){
            if (typeof(str)!='string'){
                console.log("输入不是字符串")
                return []
            }
            let arr = str.split(",")
            if (arr.length == 0){
                return []
            }else {
                return arr.map(Number)
            }
        },
        get_task_detail(id) {
            let data = {"id":id}
            post(task_detail,data).then(response=>{
                let data = response.data
                data.nodes = this.str_to_num_array(data.nodes)
                this.task_edit = data
                
            })  
        },
        // 提交编辑任务
        submit_edit_task(name){
            let validate = false
            this.$refs[name].validate((valid) => {
                if (valid) validate = true
            })
            if(!validate) {
                this.$Message.error("校验失败")
                return
            }
            console.log(this.task_edit.timeout)
            if(this.task_edit.timeout !=0 && this.task_edit.timeout<30) {
                this.$Message.error("超时设置不能小于30s")
                return
            }
            if (this.task_edit.type==2 && this.task_edit.package == ""){
                this.$Message.error("必须上传任务包")
                return
            }
            if(this.nodeKeys.length==0) {
                this.$Message.error("必须选择至少一个节点")
                return 
            }
            let data = JSON.parse(JSON.stringify(this.task_edit))
            if(data.nodes){
                // data.nodes = data.nodes.join(",")
                
                data.nodes = this.nodeKeys.map(item=>parseInt(item)).sort().join(",")
                // console.log("提交的数据节点:",data.nodes)
            }
            post(task_update,data).then( (response) => {
                if(response.status==200) {
                    this.$Message.success('更新成功')
                    this.show_edit_task_modal = false
                    this.refresh()
                }
            }).catch(error=>{
                alert(error)
            })    
        },
        btn_run_once_task(index){
            let id = this.show_list[index].id
            let data = {"id":id}
            post(task_run_once,data).then( (response) => {
                if(response.status==200) {
                    this.$Message.success('手动运行成功')
                    this.refresh()
                }else {
                    alert("手动运行失败")
                }
            })
        },
        btn_stop_task(index){
            let id = this.show_list[index].id
            let data = {"id":id}
            post(task_stop,data).then( (response) => {
                if(response.status==200) {
                    this.$Message.success('停止成功')
                    this.refresh()
                }
            })
        },
        btn_start_task(index){
            let id = this.show_list[index].id
            let data = {"id":id}
            post(task_start,data).then( (response) => {
                if(response.status==200) {
                    this.$Message.success('添加成功')
                    this.refresh()
                }
            })
        },
        get_node_list(){
            post(task_node_simple_list).then(response=>{
                let data = response.data
                this.node_list = data
            })
        },
        // 穿梭框左侧数据
        get_node_data(){
            let node_data = [];
            let node_list = this.node_list;
            let nodeIds =   this.task_edit.nodes;
            for(let i=0;i<node_list.length;i++){
                if (nodeIds.indexOf(node_list[i].id) == -1){
                    node_data.push({
                        key: node_list[i].id.toString(),
                        label: node_list[i].alias+"("+node_list[i].host+")",
                        description: node_list[i].alias,
                        // disabled:false
                    })
                }else{
                        node_data.push({
                        key: node_list[i].id.toString(),
                        label: node_list[i].alias+"("+node_list[i].host+")",
                        description: node_list[i].alias,
                        // disabled: true
                    })
                }
            }
            // console.log("左侧节点数据:",node_data)
            this.nodeData = node_data;
        },
        //穿梭框右侧数据
        get_node_keys(){
            // 要转字符串
            let keys =this.task_edit.nodes.map(item=>item.toString());
            console.log("已选节点:",keys)
            this.nodeKeys = keys;
        },
        renderX(item){
            return item.label;
        },
        handleChangeNode(newTargetKeys){
            this.nodeKeys = newTargetKeys;
        },
        // 编辑
        btn_edit_task(index){
            if (this.show_list[index].status == STATE_RUNNING){
                alert("正在运行的任务无法编辑,请先停止")
                return
            }
            this.get_task_detail(this.show_list[index].id)
            this.get_node_list()
            setTimeout(() => {
                this.get_node_data()
            },100),
            setTimeout(() => {
                this.get_node_keys()
            },100),
            setTimeout(() =>{
                this.show_edit_task_modal=true
            },300); 
        },
        submit_add_task(name){
            let validate = false
            this.$refs[name].validate((valid) => {
                if (valid) validate = true
            })
            if(!validate) {
                this.$Message.error("校验失败")
                return
            }
            let data = this.task
            post(task_add,data).then( (response) => {
                console.log(response.status)
                if(response.status==200) {
                    this.$Message.success('添加成功')
                    this.show_add_task_modal = false
                    this.refresh()
                }
            }).catch(error=>{
                console.log(error)
                alert(error)
            })    
        },

        // 添加任务
        btn_add_task(){
            
            this.show_add_task_modal = true
        },
        changePage(page) {
            this.page=page
            this.refresh()
        },
        // 每页条数变更
        changePageSize(pageSize){
            this.pageSize = pageSize
            this.refresh()
        },
        refresh() {
            let data = {
                "pageSize":this.pageSize,
                "page":this.page,
            }
            post(get_task_list,data).then(response =>{
                let data = response.data
                this.total  = data.total
                this.show_list = data.data
            })
        }
    },
    mounted: function() {
        setTimeout(() =>{
            this.refresh();
        },200); 
    }
}
</script>

<style lang="less">
    pre{
        white-space: pre-wrap!important;
        word-wrap: break-word!important;
        *white-space:normal!important;
    }
    .button-link {
        font-size:18px;
        color: black;
        padding:5px;
        line-height:30px;
    }
    .vertical-center-modal{
        display: flex;
        align-items: center;
        justify-content: center;

        .ivu-modal{
            top: 0;
        }
    }
</style>